package minimips
import (
	      "fmt"
	      "dumpwave"
	  )

func decode(
	decode_instr chan uint,
	decodeExecute chan DEEX,
	execute_rd chan int,
	dmem_datain chan int,
	dmem_dataout chan int,
	end 	chan int) {

	var register = [] int {
		0x0000000,
		0x0000000,
		0x0000000,
		0x0000000,
		0x0000000,
		0x0000000,
		0x0000000,
		0x0000000}

	for {
		instr :=<- decode_instr
		if instr == 0 {
			end <- 12
		}
		
		fmt.Printf("[decode] INSTR <-- FETCH: 0x%x\n", instr)
		fun:= instr & 0x3F
		op := (instr & 0xFC000000)>>26
		rs := (instr & 0xE00000)>>21
		rt := (instr & 0x070000)>>16
		rd := (instr & 0x3800)>>11
		of :=  instr & 0xFFFF
		//fmt.Printf("[decode] OP: 0x%x\n", op)
		
		switch op {
			case 0x0: //ULA op
				reg_rs := register[rs]
				reg_rt := register[rt]
				fmt.Printf("[decode] Reg_rt: %d | Reg_rs:%d\n", reg_rs, reg_rt)
				fmt.Printf("[decode] DEEX --> EXECUTE: (ULA OP: 0x%x)\n",op)
				
				dumpwave.Wave(1,"decodeExecuteRA")
				dumpwave.Wave(int(op),"decodeExecute")
				decodeExecute <- DEEX{op: op, rs: reg_rs, rt: reg_rt, function: fun, offset: 0}
				dumpwave.Wave(0,"decodeExecuteRA")
				
				register[rd] =<- execute_rd
				fmt.Printf("[decode] REG_RD[%d] <-- EXECUTE: 0x%x \n",rd,register[rd])
			case 0x4: //beq
				fmt.Printf("[decode] DEEX --> EXECUTE: (BEQ OP: 0x%x)\n",op)
				dumpwave.Wave(1,"decodeExecuteRA")
				dumpwave.Wave(int(op),"decodeExecute")
				decodeExecute <- DEEX{op: op, rs: register[rs], rt: register[rt], function: 0, offset: 0}
				dumpwave.Wave(0,"decodeExecuteRA")
			case 0x23: //lw
				fmt.Printf("[decode] DEEX --> EXECUTE: (LW OP: 0x%x)\n",op)
				dumpwave.Wave(1,"decodeExecuteRA")
				dumpwave.Wave(int(op),"decodeExecute")
				decodeExecute <- DEEX{op: op, rs: register[rs] , rt: 0, function: uint(0), offset: of}
				dumpwave.Wave(0,"decodeExecuteRA")
				register[rt] =<- dmem_dataout
				fmt.Printf("[decode] REG_RT[%d] <-- DMEM: 0x%x\n",rt,register[rt])
			case 0x2B: //sw
				fmt.Printf("[decode] DEEX --> EXECUTE: (SW OP: 0x%x)\n",op)
				dumpwave.Wave(1,"decodeExecuteRA")
				dumpwave.Wave(int(op),"decodeExecute")
				decodeExecute <- DEEX{op: op, rs: register[rs], rt: 0, function: 0, offset: of}
				dumpwave.Wave(0,"decodeExecuteRA")
				dumpwave.Wave(1,"dmem_datainRA")
				dumpwave.Wave(register[rt],"dmem_datain")
				dmem_datain <- register[rt]
				dumpwave.Wave(0,"dmem_datainRA")
				fmt.Printf("[decode] DATAIN <-- REGISTER[%d]: %d \n",rt,register[rt])
				
			case 0x08://addi
				reg_rs := register[rs]
				reg_rt := register[rt]
				immediate := of
				dumpwave.Wave(1,"decodeExecuteRA")
				dumpwave.Wave(int(op),"decodeExecute")
				decodeExecute <- DEEX{op: op, rs: reg_rs, rt: reg_rt, function: 0, offset: immediate}
				dumpwave.Wave(0,"decodeExecuteRA")
				
				register[rt] =<- execute_rd
				fmt.Printf("[decode] REG_RD[%d] <-- EXECUTE: 0x%x \n",rd,register[rt])
				
			default: //undefined
				fmt.Println("ERRO: Illegal instruction [decode]")
		}
		fmt.Println("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tREGISTRADORES:",register)
	}
}
